import json

from django.core.serializers.json import DjangoJSONEncoder
from model_utils.managers import SoftDeletableQuerySet

from .model_to_dict import django_model_to_dict
from .name_convert import dict_key_convert_to_camel


class Result:
    code = 200
    message = None
    data = None

    def __init__(self, code: int, message: str, data: object):
        self.code = code
        self.message = message
        self.data = data

    def __str__(self, null=False, safe=None, delete: list = None, model_newly: list = None):
        if isinstance(self.data, SoftDeletableQuerySet):
            self.data = list(self.data)
            for i in range(len(self.data)):
                self.data[i] = django_model_to_dict(self.data[i], model_newly=model_newly)
        try:
            dict_str = dict_key_convert_to_camel({
                'code': self.code,
                'message': self.message,
                'data': django_model_to_dict(self.data, model_newly=model_newly)
            }, null, safe, delete)

        except AttributeError:
            dict_str = dict_key_convert_to_camel({
                'code': self.code,
                'message': self.message,
                'data': self.data
            }, null, safe, delete)

        return json.dumps(dict_str, cls=DjangoJSONEncoder)

    @classmethod
    def success(cls, code=200, message='操作成功', data=None, null=False, safe=None, delete: list = None,
                model_newly: list = None):
        return cls.return_result(code, message, data, null, safe, delete, model_newly)

    @classmethod
    def fail(cls, code=400, message='操作失败', data=None, null=False, safe=None, delete: list = None,
             model_newly: list = None):
        return cls.return_result(code, message, data, null, safe, delete, model_newly)

    @classmethod
    def return_result(cls, code: int, message: str, data: object, null=False, safe=None, delete: list = None,
                      model_newly: list = None):
        return json.loads(Result(code, message, data).__str__(null, safe, delete, model_newly))
